"""
coding = 'utf-8'
writingtime:2022-8-7
author: zhaoweijun
reference:
doi:
examiner:
"""
from math import *

from Utilities.AutoGetOperator.selectPackage import get_func

Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')

class Weber(Operator_IVQ_ROFS):

    def add(self, a1, a2, q=0, w=2, *waste1, **waste2):
        """
        function: weber算子的基础和函数
        return: 计算结果 模糊集区间 例:([x, y], [x, y])
        """
        if q <= 0:
            q = self.q
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        u1 = min(1.0, (pow(u_1_f, q)+pow(u_2_f, q)-(w/(1+w))*pow(u_1_f, q)*pow(u_2_f, q)))**(1/q)
        u2 = min(1.0, (pow(u_1_r, q)+pow(u_2_r, q)-(w/(1+w))*pow(u_1_r, q)*pow(u_2_r, q)))**(1/q)
        v1 = max(0.0, ((pow(v_1_f, q)+pow(v_2_f, q)+w*pow(v_1_f, q)*pow(v_2_f, q)-1)/(1+w)))**(1/q)
        v2 = max(0.0, ((pow(v_1_r, q)+pow(v_2_r, q)+w*pow(v_1_r, q)*pow(v_2_r, q)-1)/(1+w)))**(1/q)
        # return ([min(1, u1), min(1, u2)], [max(0,v1), max(0, v2)])     # v1和v2计算结果为复数, 无法比较大小
        return ([u1, u2], [v1, v2])

    def multi(self, a1, a2,  q=0, w=2, *waste1, **waste2):
        """
        function: weber算子基础积函数
        return: 计算结果 模糊集区间 例:([x, y], [x, y])
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        u1 = max(0.0, ((pow(u_1_f, q)+pow(u_2_f, q)+w*pow(u_1_f, q)*pow(u_2_f, q)-1)/(1+w)))**(1/q)
        u2 = max(0.0, ((pow(u_1_r, q)+pow(u_2_r, q)+w*pow(u_1_r, q)*pow(u_2_r, q)-1)/(1+w)))**(1/q)
        v1 = min(1.0, (pow(v_1_f, q)+pow(v_2_f, q)-(w/(1+w))*pow(v_1_f, q)*pow(v_2_f, q)))**(1/q)
        v2 = min(1.0, (pow(v_1_r, q)+pow(v_2_r, q)-(w/(1+w))*pow(v_1_r, q)*pow(v_2_r, q)))**(1/q)
        # return ([max(0, u1), max(0, u2)], [min(1, v1), min(1, v2)])
        return ([u1, u2], [v1, v2])


    def kmulti(self, a1, q=0, w=2, l=2, *waste1, **waste2):
        """
        function: weber算子数乘函数
        return: 计算结果 模糊集区间 例:([x, y], [x, y])
        利用基础和函数将两个a1相加, 看结果的2落在什么位置, 再将2换成参数l
        """
        u_f, u_r, v_f, v_r = *a1[0], *a1[1]
        if q <= 0:
            q = self.q
        u1 = min(1.0, (l*pow(u_f, q)-(w/(1+w))*pow(u_f, l*q)))**(1/q)
        u2 = min(1.0, (l*pow(u_r, q)-(w/(1+w))*pow(u_r, l*q)))**(1/q)
        v1 = max(0.0, ((l*pow(v_f, q)+w*pow(v_f, l*q)-1)/(1+w)))**(1/q)
        v2 = max(0.0, ((l*pow(v_r, q)+w*pow(v_r, l*q)-1)/(1+w)))**(1/q)
        # return ([min(1, u1), min(1, u2)], [max(0, v1), max(0, v2)])     # v1和v2计算结果为复数, 无法比较大小
        return ([u1, u2], [v1, v2])

    def pow(self, a1, q=0, w=2, l=2, *waste1, **waste2):
        """
       function: weber算子乘方函数
       return :计算结果 模糊集区间 例:([x, y], [x, y])
       利用基础积函数将两个a1相乘, 看结果的2落在什么位置, 再将2换成参数l
        """
        u_f, u_r, v_f, v_r = *a1[0], *a1[1]
        if q <= 0:
            q = self.q
        u1 = max(0.0, ((l*pow(u_f, q)+w*pow(u_f, l*q)-1)/(1+w)))**(1/q)
        u2 = max(0.0, ((l*pow(u_r, q)+w*pow(u_r, l*q)-1)/(1+w)))**(1/q)
        v1 = min(1.0, (l*pow(v_f, q)-(w/(1+w))*pow(v_f, l*q)))**(1/q)
        v2 = min(1.0, (l*pow(v_r, q)-(w/(1+w))*pow(v_r, l*q)))**(1/q)
        # return ([max(0, u1), max(0, u2)], [min(1, v1), min(1, v2)])
        return ([u1, u2], [v1, v2])

class WeberA(Weber):

    def getResult(self):
        """
        function: 算术平均公式
        return: AA公式计算结果
        """
        result = self.data_list[0]
        for i in range(1, len(self.data_list)):
            result = self.multi(result, self.data_list[i])
        result = self.kmulti(result, 1/len(self.data_list))
        return result

class WeberGA(Weber):

    def getResult(self):
        """
        function: 基础的算数平均公式
        return: GAA公式计算结果
        """
        result = self.data_list[0]
        for i in range(1, len(self.data_list)):
            result = self.multi(result, self.data_list[i])
        result = self.pow(result, 1/len(self.data_list))
        return result

class WeberWA(Weber):

    def getResult(self):
        """
        function: 基础的加权算数平均公式
        return: WAA公式计算结果
        """
        result = self.kmulti(self.data_list[0], self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp = self.kmulti(self.data_list[i], self.weight_list[i])
            result = self.add(result, temp)
        return result

class WeberWGA(Weber):

    def getResult(self):
        """
        function: 基础的加权几何平均公式
        return: WGAA公式计算结果
        """
        result = self.pow(self.data_list[0], self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp = self.pow(self.data_list[i], self.weight_list[i])
            result = self.multi(result, temp)
        return result

class WeberOWA(Weber):

    def getResult(self):
        """
        function: 基础的有序加权算数平均公式
        return: OWAA公式计算结果
        """
        data_list = self.data_list
        self.data_list = self.sortdata()

        result = self.kmulti(self.data_list[0], self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp = self.kmulti(self.data_list[i], self.weight_list[i])
            result = self.add(result, temp)

        # 还原数据集
        self.data_list = data_list
        return result

if __name__ == "__main__":
    data = [([0.31, 0.24], [0.73, 0.72]), ([0.8, 0.52], [0.73, 0.15]), ([0.91, 0.49], [0.42, 0.47]), ([0.95, 0.06], [0.19, 0.1])]
    weight_list = [0.1, 0.2, 0.3, 0.1, 0.3]
    data2 = ([0.2, 0.53], [0.51, 0.67])
    # weight_list = [([0.97, 0.12], [0.12, 0.05])]
    result = weber(data, weight_list, 2, 2, 2)
    # print(result.add(data2, data2, 2))               # 测试a1+a1是否等于2*a1
    # print(result.kmulti(data2, 2))                     # 测试a1+a1是否等于2*a1
    # print(result.multi(data2, data2, 2))           # 测试a1*a1是否等于a1平方
    # print(result.pow(data2, 2))                    # 测试a1*a1是否等于a1平方, 以上结果均正确
    print(result.getResult())


